﻿using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Net.Mail;
using System.Text;

using Lenovo.CFI.BLL.DicMgr;
using Lenovo.CFI.BLL.Mail;
using Lenovo.CFI.BLL.Sys;
using Lenovo.CFI.Common;
using Lenovo.CFI.Common.Dic;
using Lenovo.CFI.Common.Mail;
using Lenovo.CFI.Common.Sys;
using Lenovo.CFI.DAL;
using Lenovo.CFI.DAL.Sys;

namespace Lenovo.CFI.BLL
{
    public class TopicBl
    {
        #region get topic

        public Topic GetTopicByID(int id)
        {
            return TopicDa.GetTopicByID(id);
        }

        public List<Topic> GetTopic()
        {
            return TopicDa.GetTopics(null, null, null, null);
        }

        public List<Topic> GetTopic(int? year, string number, TopicStatus? status, TopicStatus? notStatus)
        {
            return TopicDa.GetTopics(year, number, status, notStatus);
        }

        /*

        /// <summary>
        /// 查询没有关闭的Topic
        /// </summary>
        /// <returns></returns>
        public List<Topic> GetTopicListNotFinished()
        {
            return TopicDa.GetTopics(null, null, null, TopicStatus.Closed);
        }

        /// <summary>
        /// 查询关闭的Topic
        /// </summary>
        /// <returns></returns>
        public List<Topic> GetTopicListFinished()
        {
            return TopicDa.GetTopics(null, null, TopicStatus.Closed, null);
        }

        /// <summary>
        /// 获取需要上传PPT资料的Topic列表
        /// </summary>
        /// <returns></returns>
        public List<Topic> GetTopicKickoffList()
        {
            return TopicDa.GetTopics(null, null, TopicStatus.Create, null).FindAll(t => t.PptFileID == null);
        }

        /// <summary>
        /// 获取需要Review的Topic列表
        /// </summary>
        /// <returns></returns>
        public List<Topic> GetTopicReviewList()
        {
            return TopicDa.GetTopics(null, null, TopicStatus.Review, null);
        }

        /// <summary>
        /// 返回idea提交deadline之前的topic，状态为start
        /// </summary>
        /// <returns></returns>
        public List<Topic> GetOngoingTopicList()
        {
            List<Topic> topics = TopicDa.GetTopics(null, null, TopicStatus.Start, null);
            //返回idea提交deadline之前的topic
            return topics.FindAll(t => t.DeadlineTime > DateTime.Now);
        }


        */
        #endregion

        #region reviewers, dc and ip

        public IList<IdeaType> GetDefaultDCOwner()
        {
            return IdeaTypeDicMgr.dicMgr.GetList(false);
        }

        public string GetDefaultIPOwner()
        {
            return new SysParaBl().GetIPOwner();
        }

        public string GetDefaultReviewer()
        {
            return new SysParaBl().GetTopicReviewers();
        }

        public void SaveDefaultDCOwner(Dictionary<string, string> dcOwners)
        {
            foreach (var dcOwner in dcOwners)
            {
                User user = UserDa.GetUserByItCode(dcOwner.Value);
                if (user == null) throw new BusinessObjectLogicException("Invalid DC Owner!");

                IdeaType it = IdeaTypeDicMgr.dicMgr.GetEntry(dcOwner.Key);
                it.DC = dcOwner.Value;

                IdeaTypeDicMgr.dicMgr.Update(it);
            }
        }

        public void SaveDefaultIPOwner(string owner)
        {
            User user = UserDa.GetUserByItCode(owner);
            if (user == null) throw new BusinessObjectLogicException("Invalid IP Owner!");
            new SysParaBl().SaveIPOwner(owner);
        }

        public void SaveDefaultReviewer(string reviewers)
        {
            string[] itcodes = CodeList.SplitStringToList(reviewers);
            List<User> users = UserDa.GetUserByItCode(itcodes);
            foreach (string itcode in itcodes)
            {
                if (!users.Exists(u=>u.ItCode == itcode))
                    throw new BusinessObjectLogicException("Reviewer!");
            }

            new SysParaBl().SaveTopicReviewers(reviewers);
        }


        public List<TopicDcIp> GetDCAndIPOwner(int topicID)
        {
            return TopicDa.GetTopicDcIp(topicID);
        }

        public List<TopicReviewer> GetReviewer(int topicID)
        {
            return TopicDa.GetTopicReviewer(topicID, null, null, null);
        }

        public List<TopicReviewer> GetReviewer(int topicID, string reviewerOrAgent)
        {
            return TopicDa.GetTopicReviewer(topicID, null, null, reviewerOrAgent);
        }

        public bool IsReviewer(int topicID, string reviewer)
        {
            return TopicDa.GetTopicReviewer(topicID, reviewer, null, null).Count > 0;
        }

        public string GetAgent(int topicID, string reviewer)
        {
            List<TopicReviewer> reviewers = TopicDa.GetTopicReviewer(topicID, reviewer, null, null);

            if (reviewers.Count > 0) return reviewers[0].Agent;
            else return null;
        }

        public void SetAgent(int topicID, string reviewer, string agent) 
        {
            List<TopicReviewer> reviewers = TopicDa.GetTopicReviewer(topicID, reviewer, null, null);

            if (reviewers.Count > 0)
            {
                TopicReviewer review = reviewers[0];
                review.Agent = agent;

                TopicDa.UpdateTopicReviewer(review);
            }
            else
                throw new BusinessObjectLogicException("Invalid reviewer or agent!");
        }

        public List<string> GetDcTypes(string dcOwner, int topicID)
        {
            List<string> dcTypes = new List<string>();
            foreach (TopicDcIp dc in TopicDa.GetTopicDcIp(topicID, dcOwner, null, false))
            {
                dcTypes.Add(dc.Aspect);
            }

            return dcTypes;
        }

        public List<int> GetDcTopic(string dcOwner, out Dictionary<int, List<string>> dcTypes)
        {
            List<TopicDcIp> dcs = TopicDa.GetTopicDcIp(null, dcOwner, null, false);

            dcTypes = new Dictionary<int, List<string>>();
            List<int> topics = new List<int>();
            foreach (TopicDcIp dc in dcs)
            {
                if (!dcTypes.ContainsKey(dc.TopicID))
                {
                    dcTypes.Add(dc.TopicID, new List<string>());
                }

                dcTypes[dc.TopicID].Add(dc.Aspect);
            }

            topics.AddRange(dcTypes.Keys);

            return topics;
        }

        public List<int> GetIpTopic(string ipOwner)
        {
            List<TopicDcIp> dcs = TopicDa.GetTopicDcIp(null, ipOwner, null, true);

            List<int> topics = new List<int>();
            foreach (TopicDcIp dc in dcs)
            {
                if (dc.IsIP) topics.Add(dc.TopicID);
            }

            return topics;
        }

        public List<int> GetReviewTopic(string reviewerOrAgent, out Dictionary<int, List<string>> topicReviewers)
        {
            List<TopicReviewer> trs = TopicDa.GetTopicReviewer(null, null, null, reviewerOrAgent);

            topicReviewers = new Dictionary<int, List<string>>();
            List<int> topics = new List<int>();
            foreach (TopicReviewer tr in trs)
            {
                if (!topicReviewers.ContainsKey(tr.TopicID))
                {
                    topicReviewers.Add(tr.TopicID, new List<string>());
                }

                topicReviewers[tr.TopicID].Add(tr.Reviewer);
            }

            topics.AddRange(topicReviewers.Keys);

            return topics;
        }

        #endregion


        #region Create topic

        /// <summary>
        /// 创建新的Topic
        /// </summary>
        /// <param name="topic"></param>
        public void CreateTopic(Topic topic, Dictionary<string, string> dcUsers, string ipUser, List<string> reivewers, List<string> mailTo)
        {
            // No不能重复
            List<Topic> topics = TopicDa.GetTopics(null, topic.No, null, null);
            if (topics.Count > 0)
                throw new BusinessObjectLogicException(string.Format("Topic No. {0} is used by another topic", topic.No));


            // Start and Deadline Time 必填
            if (!topic.StartTime.HasValue || !topic.DeadlineTime.HasValue || topic.StartTime >= topic.DeadlineTime)
                throw new BusinessObjectLogicException("The Start Time and/or Deadline Time is invalid!");

            if (topic.ReviewTime.HasValue && topic.DeadlineTime > topic.ReviewTime)
                throw new BusinessObjectLogicException("The Review Time is invalid!");

            if (topic.Year == 0) topic.Year = DateTime.Now.Year;

            List<string> itcodes = new List<string>();
            itcodes.Add(topic.Tdc);
            itcodes.AddRange(dcUsers.Values);
            itcodes.Add(ipUser);
            itcodes.AddRange(reivewers);
            Dictionary<string, bool> existUsers = new Dictionary<string, bool>();
            foreach (User user in UserDa.GetUserByItCode(itcodes.ToArray()))
                existUsers.Add(user.ItCode, true);
            if (!existUsers.ContainsKey(topic.Tdc))
                throw new BusinessObjectLogicException("The T-DC is invalid!");
            foreach (string u in dcUsers.Values)
            {
                if (!existUsers.ContainsKey(u))
                    throw new BusinessObjectLogicException("The DC Owner is invalid!");
            }
            if (!existUsers.ContainsKey(ipUser))
                throw new BusinessObjectLogicException("The IP Owner is invalid!");
            foreach (string u in reivewers)
            {
                if (!existUsers.ContainsKey(u))
                    throw new BusinessObjectLogicException("The Reivewer is invalid!");
            }

            topic.CreateTime = DateTime.Now;
            topic.Status = TopicStatus.Create;

            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.InsertTopic(topic, trans);

                    foreach (var dcUser in dcUsers)
                    {
                        TopicDcIp dc = new TopicDcIp();
                        dc.TopicID = topic.ID;
                        dc.User = dcUser.Value;
                        dc.Aspect = dcUser.Key;
                        TopicDa.InsertTopicDcIp(dc, trans);
                    }

                    TopicDcIp ip = new TopicDcIp();
                    ip.TopicID = topic.ID;
                    ip.User = ipUser;
                    ip.Aspect = null;
                    TopicDa.InsertTopicDcIp(ip, trans);


                    foreach (string reviewer in reivewers)
                    {
                        TopicReviewer tr = new TopicReviewer(topic.ID, reviewer);
                        tr.Agent = reviewer;
                        TopicDa.InsertTopicReviewer(tr, trans);
                    }



                    // 通知Reviewer
                    //subject = "xxx";
                    //content = String.Format(@"你好!!",
                    //    topic.StartTime, topic.Title, topic.StartTime.Value.AddDays(-5));
                    //MailBl.SendMail(trans, MailBl.ConvertMailAddress(reivewers), null, subject, content, MailPriority.Normal);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }

            // 发送邮件，通知TDC
            new MailBl().MailTopicTdc(topic.ID, topic.Title, topic.StartTime.Value, MailBl.ConvertMailAddress(mailTo));
        }

        public void EditTopic(int id, int year, string no, string tdc, DateTime start, DateTime deadLine, DateTime? review, Guid? pptID)
        {
            Topic topic = TopicDa.GetTopicByID(id);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Create) throw new BusinessObjectLogicException("The specified topic can't be changed!");


            // topic.Year = year;
            topic.No = no;
            topic.Tdc = tdc;
            topic.StartTime = start;
            topic.DeadlineTime = deadLine;
            topic.ReviewTime = review;
            topic.PptFileID = pptID;

            TopicDa.UpdateTopic(topic);
        }

        public void EditTopic(int id, DateTime suggestDate, DateTime materialDate, DateTime reportDate, DateTime mktDate, string principal)
        {
            Topic topic = TopicDa.GetTopicByID(id);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            topic.SuggestDate = suggestDate;
            topic.MaterialDate = materialDate;
            topic.ReportDate = reportDate;
            topic.MktDate = mktDate;
            topic.Principal = principal;

            TopicDa.UpdateTopic(topic);
        }

        public void EditTopicDcAndIp(int topicID, Dictionary<string, string> dcUsers, string ipUser)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Create && 
                topic.Status != TopicStatus.Summary) throw new BusinessObjectLogicException("The specified topic can't be changed!");


            List<string> itcodes = new List<string>();
            itcodes.AddRange(dcUsers.Values);
            itcodes.Add(ipUser);
            Dictionary<string, bool> existUsers = new Dictionary<string, bool>();
            foreach (User user in UserDa.GetUserByItCode(itcodes.ToArray()))
                existUsers.Add(user.ItCode, true);
            foreach (string u in dcUsers.Values)
            {
                if (!existUsers.ContainsKey(u))
                    throw new BusinessObjectLogicException("The DC Owner is invalid!");
            }
            if (!existUsers.ContainsKey(ipUser))
                throw new BusinessObjectLogicException("The IP Owner is invalid!");


            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.DeleteTopicDcIp(topicID, trans);


                    foreach (var dcUser in dcUsers)
                    {
                        TopicDcIp dc = new TopicDcIp();
                        dc.TopicID = topic.ID;
                        dc.User = dcUser.Value;
                        dc.Aspect = dcUser.Key;
                        TopicDa.InsertTopicDcIp(dc, trans);
                    }

                    TopicDcIp ip = new TopicDcIp();
                    ip.TopicID = topic.ID;
                    ip.User = ipUser;
                    ip.Aspect = null;
                    TopicDa.InsertTopicDcIp(ip, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }

        public void EditTopicReivewers(int topicID, List<string> reivewers)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Create && 
                topic.Status != TopicStatus.Reviewer) throw new BusinessObjectLogicException("The specified topic can't be changed!");

            List<string> itcodes = new List<string>();
            itcodes.AddRange(reivewers);
            Dictionary<string, bool> existUsers = new Dictionary<string, bool>();
            foreach (User user in UserDa.GetUserByItCode(itcodes.ToArray()))
                existUsers.Add(user.ItCode, true);
            foreach (string u in reivewers)
            {
                if (!existUsers.ContainsKey(u))
                    throw new BusinessObjectLogicException("The Reivewer is invalid!");
            }

            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.DeleteTopicReviewer(topicID, trans);

                    foreach (string reviewer in reivewers)
                    {
                        TopicReviewer tr = new TopicReviewer(topicID, reviewer);
                        tr.Agent = reviewer;
                        TopicDa.InsertTopicReviewer(tr, trans);
                    }

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }

        public void RemoveTopic(int id)
        {
            Topic topic = TopicDa.GetTopicByID(id);
            if (topic.Status != TopicStatus.Create) throw new BusinessObjectLogicException("The specified topic can't be deleted!");

            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.DeleteTopic(id, trans);     // SP处理相关数据的删除 -- 级联

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }


        #endregion

        #region Process topic

        /// <summary>
        /// 完成准备材料的上传
        /// </summary>
        /// <param name="topic"></param>
        public void UploadKickOffMaterials(int topicID, Guid pptID)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Create) throw new BusinessObjectLogicException("The specified topic can't be changed!");

            topic.PptFileID = pptID;

            List<User> assistants = UserDa.GetUserWithRole(UserRole.ROLE_ASSISTANT1);

            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.UpdateTopic(topic, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }

            // 发送邮件 通知 助理1
            new MailBl().MailTopicReady(topic.ID, topic.Title, MailBl.ConvertMailAddress(assistants));
        }

        public void StartTopic(int topicID)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Create) throw new BusinessObjectLogicException("The specified topic has been changed!");

            topic.Status = TopicStatus.Start;
            TopicDa.UpdateTopic(topic);


            // 记录此时有效的Team信息
            List<string> ids = new List<string>();
            foreach (Team team in TeamDa.GetTeam(true, true, null, null))
            {
                ids.Add(team.ID.ToString());
            }
            new SysParaBl().SaveTopicTeamList(topic.ID, CodeList.ConvertListToString(ids));

        }

        public void PrepareSchedule(int topicID) 
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Start) throw new BusinessObjectLogicException("The specified topic has been changed!");

            topic.Status = TopicStatus.Schedule;

            List<Idea> ideas = IdeaDa.GetIdeaByBelongTopic(topicID);                                                 // 此次Topic的Idea

            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.UpdateTopic(topic, trans);

                    // 更新状态
                    foreach (Idea idea in ideas)
                    {
                        if (idea.Status == IdeaStatus.Agree || idea.Status == IdeaStatus.Submitted)
                        {
                            idea.Status = IdeaStatus.ReviewPreparing;
                            IdeaDa.UpdateIdea(idea, trans);
                        }
                    }

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }

            TopicDa.UpdateTopic(topic);



            // 更新此时有效的Team信息 -- TODO:会不会有Team失效？不确定
            List<string> ids = new List<string>();
            foreach (Team team in TeamDa.GetTeam(true, true, null, null))
            {
                ids.Add(team.ID.ToString());
            }
            new SysParaBl().SaveTopicTeamList(topic.ID, CodeList.ConvertListToString(ids));
        }
        

        /// <summary>
        /// 完成评审时间表，发送通知
        /// </summary>
        /// <param name="topicID"></param>
        public void FinishSchedule(int topicID)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Schedule) throw new BusinessObjectLogicException("The specified topic has been changed!");

            topic.Status = TopicStatus.Reviewer;


            //List<ScheduleDetail> scheduleDetails = ScheduleDa.GetTopicReviewSchedule(topicID);        // 评审安排
            //ReviewScheduleBl.ComputeTimeTable(scheduleDetails);                                       // 计算时间表
            List<ScheduleDetail> scheduleDetails = new ScheduleBl().GetScheduleWithTimeTable(topicID);
            List<Idea> ideas = IdeaDa.GetIdeaByBelongTopic(topicID);                                    // 此次Topic的Idea
            Dictionary<int, Idea> ideasDic = new Dictionary<int, Idea>();
            foreach (Idea idea in ideas) ideasDic.Add(idea.ID, idea);

            scheduleDetails = scheduleDetails.FindAll(d => d.EventType == ScheduleEventType.Idea);
            scheduleDetails.Sort((x, y) => x.Sort.CompareTo(y.Sort));       // 排序

            Dictionary<int, Idea> reviewIdeasDic = new Dictionary<int, Idea>();     // 实际参与评审的Idea


            List<IdeaReview> insertReviews = new List<IdeaReview>();
            List<Idea> updateIdeas = new List<Idea>();
            Dictionary<string, bool> ideaOwners = new Dictionary<string, bool>();

            //Dictionary<Idea, IdeaReview> ideaReviewsDic = new Dictionary<Idea, IdeaReview>();

            int no = 1;
            // 确定需要Review的Idea
            foreach (ScheduleDetail scheduleDetail in scheduleDetails)
            {
                IdeaReview ideaReview = new IdeaReview(topicID, scheduleDetail.IdeaID.Value);
                ideaReview.ReviewTime = scheduleDetail.StartTime;
                ideaReview.ReviewPeriod = scheduleDetail.Period;
                ideaReview.ReviewScore = 0;     // 
                ideaReview.ReviewStatus = IdeaReviewStatus.Waiting;
                ideaReview.DcConfirmed = SuggestionStatus.None;
                ideaReview.IPConfirmed = SuggestionStatus.None;
                ideaReview.ActionStatus = ExecutionStatus.None;
                ideaReview.IpStatus = ExecutionStatus.None;
                insertReviews.Add(ideaReview);

                Idea idea = null;
                if (ideasDic.ContainsKey(scheduleDetail.IdeaID.Value))
                    idea = ideasDic[scheduleDetail.IdeaID.Value];

                //if (scheduleDetail.Period > 0)  // 实际参与评审会议的Idea
                //{
                //    reviewIdeasDic.Add(scheduleDetail.IdeaID.Value, idea);      // 可能是NULL
                //}
                // 实际参与评审的Idea
                reviewIdeasDic.Add(scheduleDetail.IdeaID.Value, idea);      // 可能是NULL

                // 本次的Topic
                if (idea != null)
                {
                    idea.No = no++; // 确定NO

                    ideaReview.ReviewType = idea.Type;
                    
                    idea.FinalReviewTopicID = topicID;      // 记录
                    idea.FinalReviewID = ideaReview.ID;     // 需要获取
                    updateIdeas.Add(idea);
                }
            }

            // 其余不参与评审的Idea -- 
            foreach (Idea idea in ideas)
            {
                if ((idea.Status == IdeaStatus.ReviewPreparing) && idea.No == 0)
                {
                    idea.No = no++; // 确定NO
                    idea.Status = IdeaStatus.ReviewCanceled;        // 不参与评审
                    updateIdeas.Add(idea);
                }
            }

            // Idea Owners
            List<int> ideaIDs = new List<int>();
            foreach (var idea in reviewIdeasDic)
            {
                if (idea.Value == null) ideaIDs.Add(idea.Key);
            }
            foreach (Idea idea in IdeaDa.GetByIDs(ideaIDs))
            {
                reviewIdeasDic[idea.ID] = idea;

                if (idea.Status != IdeaStatus.Closed) throw new BusinessObjectLogicException("The specified idea is reviewing in other topic!");

                idea.Status = IdeaStatus.ReviewPreparing;   // 更新
                idea.FinalReviewTopicID = topicID;          // 记录
                idea.FinalReviewID = 0;                     // 需要更新 -- 标记
                idea.FinalAward = null;                     // clear
                idea.FinalIP = null;
                idea.FinalAction = null;
                idea.FinalActionBU = null;
                idea.FinalActionStatus = ExecutionStatus.None;
                idea.FinalIPStatus = ExecutionStatus.None;
                idea.CanSearch = false;

                updateIdeas.Add(idea);
            }
            foreach (var idea in reviewIdeasDic)
            {
                if (!ideaOwners.ContainsKey(idea.Value.Owner))
                    ideaOwners.Add(idea.Value.Owner, true);
            }


            //List<string> reviewers = new List<string>();
            //foreach (TopicReviewer tr in TopicDa.GetTopicReviewer(topicID, null, null))
            //{
            //    reviewers.Add(tr.Reviewer);
            //}



            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.UpdateTopic(topic, trans);

                    foreach (IdeaReview ideaReview in insertReviews)
                    {
                        ReviewDa.InsertReview(ideaReview, trans);

                        if (reviewIdeasDic.ContainsKey(ideaReview.IdeaID))
                            reviewIdeasDic[ideaReview.IdeaID].FinalReviewID = ideaReview.ID;    // 更新
                    }

                    foreach (Idea idea in updateIdeas)
                        IdeaDa.UpdateIdea(idea, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }

            string content = ScheduleBl.GenerateTimeTable4Email(scheduleDetails, reviewIdeasDic);

            // 给 IdeaOwner发送邮件通知
            new MailBl().MailTopicScheduleToOwner(topic.ID, topic.Title, MailBl.ConvertMailAddress(ideaOwners.Keys), content);
        }

        /// <summary>
        /// 完成设置评审专家，进入评审环节
        /// </summary>
        /// <param name="topicID"></param>
        public void ReadyForReview(int topicID)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Reviewer) throw new BusinessObjectLogicException("The specified topic has been changed!");


            topic.Status = TopicStatus.Review;


            List<ScheduleDetail> scheduleDetails = new ScheduleBl().GetScheduleWithTimeTable(topicID);
            List<Idea> ideas = IdeaDa.GetIdeaForReview(topicID);                                                 // 此次Topic的Idea
            Dictionary<int, Idea> ideasDic = new Dictionary<int, Idea>();
            foreach (Idea idea in ideas) ideasDic.Add(idea.ID, idea);

            scheduleDetails = scheduleDetails.FindAll(d => d.EventType == ScheduleEventType.Idea);
            scheduleDetails.Sort((x, y) => x.Sort.CompareTo(y.Sort));       // 排序


            List<string> reviewers = new List<string>();
            foreach (TopicReviewer tr in TopicDa.GetTopicReviewer(topicID, null, null, null))
            {
                reviewers.Add(tr.Reviewer);
            }


            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.UpdateTopic(topic, trans);

                    foreach (Idea idea in ideas)
                    {
                        idea.Status = IdeaStatus.Reviewing; // 评审中
                        IdeaDa.UpdateIdea(idea, trans);
                    }

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }


            //给评委发送邮件

            string content = ScheduleBl.GenerateTimeTable4Email(scheduleDetails, ideasDic);

            new MailBl().MailTopicScheduleToOwner(topic.ID, topic.Title, MailBl.ConvertMailAddress(reviewers), content);
        }


        /// <summary>
        /// 完成评审，开始Summary
        /// </summary>
        /// <param name="topicID"></param>
        public void StartSummary(int topicID)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Review) throw new BusinessObjectLogicException("The specified topic has been changed!");

            topic.Status = TopicStatus.Summary;

            List<Idea> ideas = IdeaDa.GetIdeaForReview(topicID);                                                 // 此次Topic的Idea
         
            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.UpdateTopic(topic, trans);

                    ReviewDa.UpdateReviewScoreAndStatus(topic.ID, trans);

                    foreach (Idea idea in ideas)
                    {
                        idea.Status = IdeaStatus.ReviewClosed; // 评审完成
                        IdeaDa.UpdateIdea(idea, trans);
                    }

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }


        /// <summary>
        /// 完成Summary，开始NextAction
        /// </summary>
        /// <param name="topicID"></param>
        public void StartSuggestion(int topicID, DateTime suggestionDate, DateTime submitMaterialDate, DateTime gmoReportDate)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Summary) throw new BusinessObjectLogicException("The specified topic has been changed!");

            topic.Status = TopicStatus.Suggestion;

            List<Idea> ideas = IdeaDa.GetIdeaForReview(topicID);                    // 此次Topic的Idea
            List<IdeaReview> reviews = ReviewDa.GetReview(topicID);                     // 此次Topic的Idea

            Dictionary<int, IdeaReview> reviewsDic = new Dictionary<int, IdeaReview>();
            foreach (IdeaReview review in reviews) reviewsDic.Add(review.IdeaID, review);

            Dictionary<string, string> dcOwnersDic = new Dictionary<string, string>();
            string ipOwner = null;
            List<string> dcipOwners = new List<string>();
            foreach (TopicDcIp dcip in TopicDa.GetTopicDcIp(topicID))
            {
                if (dcip.IsIP)
                    ipOwner = dcip.User;
                else
                    dcOwnersDic[dcip.Aspect] = dcip.User;

                if (dcipOwners.Contains(dcip.User)) dcipOwners.Add(dcip.User);
            }

            // check
            if (ideas.Count != reviews.Count) throw new BusinessObjectLogicException("Data error!");


            if (ipOwner == null) throw new BusinessObjectLogicException("Please set all DC and IP owners!");
            foreach (Idea idea in ideas)
            {
                IdeaReview review = reviewsDic[idea.ID];

                if (String.IsNullOrEmpty(review.ReviewType))
                    throw new BusinessObjectLogicException("Please summay all idea!");

                if (!dcOwnersDic.ContainsKey(review.ReviewType))
                    throw new BusinessObjectLogicException("Please set all DC and IP owners!");

                review.DcOwner = dcOwnersDic[review.ReviewType];
                review.IPOwner = ipOwner;
            }

            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.UpdateTopic(topic, trans);

                    foreach (Idea idea in ideas)
                    {
                        idea.Status = IdeaStatus.Suggestion; // Suggestion
                        IdeaDa.UpdateIdea(idea, trans);
                    }

                    foreach(IdeaReview review in reviews)
                    {
                        ReviewDa.UpdateReview(review);
                    }

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }


            //发送邮件
            new MailBl().MailSuggestion(MailBl.ConvertMailAddress(dcipOwners), suggestionDate, gmoReportDate, submitMaterialDate);
        }

        /// <summary>
        /// 完成Suggestion，开始Execution
        /// </summary>
        /// <param name="topicID"></param>
        public void StartExecution(int topicID, DateTime gmoReportDate, DateTime mktReportDate, DateTime submitMaterialDate, string materialPrincipal)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Suggestion) throw new BusinessObjectLogicException("The specified topic has been changed!");

            topic.Status = TopicStatus.Execution;

            List<Idea> ideas = IdeaDa.GetIdeaForReview(topicID);                    // 此次Topic的Idea
            List<IdeaReview> reviews = ReviewDa.GetReview(topicID);                     // 此次Topic的Idea

            Dictionary<int, IdeaReview> reviewsDic = new Dictionary<int, IdeaReview>();
            foreach (IdeaReview review in reviews) reviewsDic.Add(review.IdeaID, review);

            Dictionary<string, User> usersDic = new Dictionary<string, User>();
            foreach (User user in UserDa.GetUserAll())
                usersDic.Add(user.ItCode, user);


            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.UpdateTopic(topic, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }

            MailBl mailBl = new MailBl();
            foreach (Idea idea in ideas)
            {
                IdeaReview review = reviewsDic[idea.ID];


                if (review.DcConfirmed == SuggestionStatus.Finished)
                {
                    mailBl.MailActionExecution(idea.ID, idea.Title, review.NextAction,
                       MailBl.ConvertMailAddress(idea.Owner), gmoReportDate, mktReportDate, submitMaterialDate, materialPrincipal);
                }

                if (review.IPConfirmed == SuggestionStatus.Finished)
                {
                    if (review.NextIP == true)
                    {
                        mailBl.MailIPExecution(idea.ID, idea.Title,
                           MailBl.ConvertMailAddress(idea.Owner), gmoReportDate, submitMaterialDate, materialPrincipal);
                    }
                }
            }
        }


        /// <summary>
        /// 关闭Topci 完成
        /// </summary>
        /// <param name="topicID"></param>
        public void CloseTopic(int topicID)
        {
            Topic topic = TopicDa.GetTopicByID(topicID);
            if (topic == null) throw new BusinessObjectLogicException("The specified topic does not exist!");

            if (topic.Status != TopicStatus.Execution) throw new BusinessObjectLogicException("The specified topic has been changed!");

            topic.Status = TopicStatus.Closed;


            using (TranscationHelper trans = TranscationHelper.GetInstance())
            {
                trans.BeginTrans();
                try
                {
                    TopicDa.UpdateTopic(topic, trans);

                    trans.CommitTrans();
                }
                catch
                {
                    trans.RollTrans();
                    throw;
                }
            }
        }

        #endregion
    }
}
